#pragma once
#include <iostream>
#include <pthread.h>
#include <string>
#include <functional>
#include"Log.hpp"

using namespace LogMoudle;

using thread_task = std::function<void(std::string name)>;

namespace ThreadMoudle
{

    enum class TSTAUS
    {
        THREAD_NEW,
        THREAD_RUNNING,
        THREAD_STOP
    };
    int cnt = 0;

    class Thread
    {
    public:
        static void *run(void *obj)
        {
            Thread *self = static_cast<Thread *>(obj);
            self->style = TSTAUS::THREAD_RUNNING;

            LOG(Logevel::INFO)<<self->getName()<<"is runing......";
            self->_func(self->getName());//这里需要传入参数
            return nullptr;
        }

        void SetName()
        {
            _name = "Thread-" + std::to_string(cnt++);
        }

        // 线程默认为joinable，线程在创建时需要，设定线程需要完成的任务
        Thread(thread_task func) : _func(func), _joined(true), style(TSTAUS::THREAD_NEW)
        {
            SetName();
        }

        void EnableDeath()
        {
            if (style == TSTAUS::THREAD_NEW)
            {
                _joined = false;
            }
        }

        void EnableJoined()
        {
            if (style == TSTAUS::THREAD_NEW)
            {
                _joined = true;
            }
        }

        bool Start()
        {
            if (style == TSTAUS::THREAD_RUNNING)
            {
                return false;
            }
            int n = pthread_create(&_td, nullptr, run, this);
            if (n != 0)
                return false;
            return true;
        }

        bool Join()
        {
            
            if (_joined)
            {
                int n = pthread_join(_td, nullptr);
                if (n == 0)
                {
                    style=TSTAUS::THREAD_STOP;
                    return true;
                }
                return false;
            }
            return false;
        }

        std::string getName()
        {
            return _name;
        }
        ~Thread()
        {
            
        }

    private:
        pthread_t _td;
        std::string _name;

        bool _joined;
        thread_task _func;
        TSTAUS style;
    };

}